#!/usr/bin/env python3
"""
BIM智能安全分析平台启动脚本
恢复原有的平台功能，支持静态文件服务和API接口
"""

import http.server
import socketserver
import os
import json
import mimetypes
from urllib.parse import urlparse, parse_qs
import threading
import time

class BIMRequestHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=".", **kwargs)
    
    def do_GET(self):
        """处理GET请求"""
        parsed_path = urlparse(self.path)
        path = parsed_path.path
        
        # 路由处理
        if path == '/' or path == '/index.html':
            self.serve_file('/static/index.html')
        elif path == '/ai-rules':
            self.serve_file('/static/ai-rules.html')
        elif path.startswith('/api/'):
            self.handle_api_request(path, parsed_path.query)
        elif path.startswith('/static/'):
            self.serve_file(path)
        else:
            # 尝试直接服务文件
            file_path = path if os.path.exists('.' + path) else '/static' + path
            self.serve_file(file_path)
    
    def do_POST(self):
        """处理POST请求"""
        parsed_path = urlparse(self.path)
        path = parsed_path.path
        
        if path == '/api/upload':
            self.handle_upload()
        elif path == '/api/ai-rules/build':
            self.handle_ai_rules_build()
        elif path.startswith('/api/admin/'):
            self.handle_admin_api(path)
        else:
            self.send_error(404, "API endpoint not found")
    
    def handle_api_request(self, path, query_string):
        """处理API请求"""
        if path == '/api/demo':
            self.serve_demo_data()
        elif path == '/api/history':
            self.serve_history()
        elif path.startswith('/api/results/'):
            result_id = path.split('/')[-1]
            self.serve_result(result_id)
        elif path == '/api/ai-rules/build':
            self.handle_ai_rules_build()
        elif path == '/api/ai-rules/demo':
            self.serve_ai_demo()
        elif path == '/api/ai-rules/history':
            self.serve_ai_history()
        elif path == '/api/admin/rules':
            self.serve_admin_rules()
        else:
            self.send_error(404, "API endpoint not found")
    
    def serve_file(self, file_path):
        """服务静态文件"""
        try:
            full_path = '.' + file_path
            if not os.path.exists(full_path):
                self.send_error(404, "File not found")
                return
            
            content_type, _ = mimetypes.guess_type(full_path)
            if not content_type:
                content_type = 'text/html'
            
            with open(full_path, 'rb') as file:
                content = file.read()
                
            self.send_response(200)
            self.send_header('Content-Type', content_type)
            self.send_header('Content-Length', str(len(content)))
            self.end_headers()
            self.wfile.write(content)
            
        except Exception as e:
            self.send_error(500, str(e))
    
    def serve_demo_data(self):
        """提供演示数据"""
        demo_data = {
            "upload_id": "demo_123",
            "filename": "演示办公楼.ifc",
            "building_type": "commercial",
            "upload_time": time.strftime('%Y-%m-%d %H:%M:%S'),
            "analysis_status": "completed",
            "summary": {
                "total_elements": 245,
                "critical_issues": 3,
                "warning_issues": 8,
                "info_issues": 15,
                "compliance_score": 87.5
            },
            "issues": [
                {
                    "severity": "critical",
                    "category": "消防安全",
                    "title": "疏散通道宽度不足",
                    "description": "主疏散通道宽度小于规范要求的最小1.4米",
                    "location": "2层走廊区域",
                    "suggested_fix": "扩大通道宽度至1.5米以上"
                },
                {
                    "severity": "warning",
                    "category": "结构安全",
                    "title": "承重墙厚度偏小",
                    "description": "部分承重墙厚度低于规范要求",
                    "location": "3层北侧墙体",
                    "suggested_fix": "增加墙体厚度或加强配筋"
                }
            ]
        }
        
        self.send_json_response(demo_data)
    
    def serve_history(self):
        """提供历史记录"""
        history = []
        results_dir = './data/results'
        
        if os.path.exists(results_dir):
            for filename in os.listdir(results_dir):
                if filename.endswith('.json'):
                    try:
                        with open(os.path.join(results_dir, filename), 'r', encoding='utf-8') as f:
                            data = json.load(f)
                            history.append({
                                "upload_id": filename.replace('.json', ''),
                                "filename": data.get('filename', '未知文件'),
                                "upload_time": data.get('upload_time', ''),
                                "building_type": data.get('building_type', ''),
                                "total_issues": len(data.get('issues', [])),
                                "compliance_score": data.get('summary', {}).get('compliance_score', 0)
                            })
                    except:
                        continue
        
        self.send_json_response(history)
    
    def serve_result(self, result_id):
        """提供具体结果"""
        result_path = f'./data/results/{result_id}.json'
        
        if os.path.exists(result_path):
            with open(result_path, 'r', encoding='utf-8') as f:
                result = json.load(f)
            self.send_json_response(result)
        else:
            self.send_error(404, "Result not found")
    
    def handle_upload(self):
        """处理文件上传"""
        # 简化处理，直接返回成功响应
        response = {
            "upload_id": f"upload_{int(time.time())}",
            "status": "processing",
            "message": "文件上传成功，正在分析..."
        }
        self.send_json_response(response)
    
    def handle_ai_rules_build(self):
        """处理AI规则构建"""
        content_length = int(self.headers.get('Content-Length', 0))
        post_data = self.rfile.read(content_length)
        
        try:
            data = json.loads(post_data.decode('utf-8'))
            building_type = data.get('building_type', 'residential')
            
            # 加载管理员规范库 + AI规则
            admin_rules = self.load_admin_standards(building_type)
            ai_rules = self.generate_ai_rules(building_type, data.get('context', {}))
            
            # 合并规则
            all_rules = admin_rules + ai_rules
            
            response = {
                "rule_set_id": f"rules_{int(time.time())}",
                "building_type": building_type,
                "total_rules": len(all_rules),
                "admin_rules_count": len(admin_rules),
                "ai_rules_count": len(ai_rules),
                "created_at": time.strftime('%Y-%m-%d %H:%M:%S'),
                "rules": all_rules
            }
            
            self.send_json_response(response)
            
        except Exception as e:
            self.send_error(500, str(e))
    
    def serve_ai_demo(self):
        """提供AI规则演示"""
        demo_rules = self.generate_ai_rules('residential', {})
        response = {
            "rule_set_id": "demo_rules",
            "building_type": "residential",
            "total_rules": len(demo_rules),
            "created_at": time.strftime('%Y-%m-%d %H:%M:%S'),
            "rules": demo_rules
        }
        self.send_json_response(response)
    
    def serve_ai_history(self):
        """提供AI规则历史"""
        # 返回空历史或模拟数据
        self.send_json_response([])
    
    def load_admin_standards(self, building_type):
        """加载管理员规范库"""
        try:
            with open('admin_standards.json', 'r', encoding='utf-8') as f:
                all_standards = json.load(f)
                
            # 过滤指定建筑类型的规范，包括all类型的通用规范
            filtered_rules = []
            for rule in all_standards:
                if rule['building_type'] == building_type or rule['building_type'] == 'all':
                    filtered_rules.append({
                        "rule_id": f"ADMIN_{rule['id']}",
                        "title": rule['title'],
                        "description": rule['description'],
                        "category": rule['category'],
                        "severity": rule['severity'],
                        "condition": rule['condition'],
                        "threshold": rule.get('threshold'),
                        "unit": rule.get('unit'),
                        "standard": rule['code'],
                        "suggested_fix": rule.get('suggested_fix', ''),
                        "source": "admin_standards"
                    })
            
            return filtered_rules
            
        except FileNotFoundError:
            return []
        except Exception:
            return []

    def generate_ai_rules(self, building_type, context):
        """生成AI规则"""
        base_rules = {
            'residential': [
                {
                    "rule_id": "AI_R001",
                    "title": "住宅层高检查",
                    "description": "住宅建筑层高不应大于3.6米",
                    "category": "功能空间",
                    "severity": "中等",
                    "condition": "floor_height > 3.6",
                    "threshold": 3.6,
                    "unit": "米",
                    "standard": "GB50368-2005",
                    "suggested_fix": "调整层高至规范范围内"
                },
                {
                    "rule_id": "AI_R002",
                    "title": "住宅采光系数检查",
                    "description": "住宅主要房间采光系数不应低于1%",
                    "category": "通风采光",
                    "severity": "轻微",
                    "condition": "light_factor < 0.01",
                    "threshold": 0.01,
                    "unit": "%",
                    "standard": "GB50033-2013",
                    "suggested_fix": "增大窗户面积或调整窗户位置"
                }
            ],
            'commercial': [
                {
                    "rule_id": "AI_C001",
                    "title": "商业建筑防火分区面积",
                    "description": "商业建筑防火分区最大允许建筑面积为2500平方米",
                    "category": "消防安全",
                    "severity": "严重",
                    "condition": "fire_zone_area > 2500",
                    "threshold": 2500,
                    "unit": "平方米",
                    "standard": "GB50016-2014",
                    "suggested_fix": "设置防火分区或防火墙"
                },
                {
                    "rule_id": "AI_C002",
                    "title": "商业建筑疏散距离",
                    "description": "商业建筑营业厅内任一点至最近疏散门或安全出口的直线距离不应大于37.5米",
                    "category": "消防安全",
                    "severity": "严重",
                    "condition": "evacuation_distance > 37.5",
                    "threshold": 37.5,
                    "unit": "米",
                    "standard": "GB50016-2014",
                    "suggested_fix": "增加疏散出口或调整布局"
                }
            ],
            'office': [
                {
                    "rule_id": "AI_O001",
                    "title": "办公建筑走道宽度",
                    "description": "办公建筑走道净宽不应小于1.4米",
                    "category": "功能空间",
                    "severity": "中等",
                    "condition": "corridor_width < 1.4",
                    "threshold": 1.4,
                    "unit": "米",
                    "standard": "JGJ67-2006",
                    "suggested_fix": "扩大走道宽度"
                }
            ]
        }
        
        rules = base_rules.get(building_type, [])
        
        # 为AI规则添加source标记
        for rule in rules:
            rule["source"] = "ai_generated"
            
        return rules
    
    def handle_admin_api(self, path):
        """处理管理员API请求"""
        # 验证管理员权限
        admin_token = self.headers.get('X-Admin-Token')
        if admin_token != 'admin-secret-2024':
            self.send_error(403, "Access denied")
            return
            
        try:
            if path == '/api/admin/rules' and self.command == 'GET':
                self.serve_admin_rules()
            elif path == '/api/admin/rules' and self.command == 'POST':
                self.add_admin_rule()
            elif path.startswith('/api/admin/rules/') and self.command == 'DELETE':
                rule_id = path.split('/')[-1]
                self.delete_admin_rule(rule_id)
            elif path == '/api/admin/rules/import' and self.command == 'POST':
                self.import_admin_rules()
            elif path == '/api/admin/rules/clear' and self.command == 'DELETE':
                self.clear_admin_rules()
            else:
                self.send_error(404, "API endpoint not found")
        except Exception as e:
            self.send_error(500, str(e))

    def serve_admin_rules(self):
        """提供管理员规范库"""
        try:
            with open('admin_standards.json', 'r', encoding='utf-8') as f:
                rules = json.load(f)
            self.send_json_response(rules)
        except FileNotFoundError:
            self.send_json_response([])
        except Exception as e:
            self.send_error(500, str(e))

    def add_admin_rule(self):
        """添加管理员规范"""
        content_length = int(self.headers.get('Content-Length', 0))
        post_data = self.rfile.read(content_length)
        
        try:
            new_rule = json.loads(post_data.decode('utf-8'))
            new_rule['id'] = f"admin_{int(time.time())}"
            new_rule['created_at'] = time.strftime('%Y-%m-%d')
            
            # 加载现有规则
            try:
                with open('admin_standards.json', 'r', encoding='utf-8') as f:
                    rules = json.load(f)
            except FileNotFoundError:
                rules = []
            
            rules.append(new_rule)
            
            # 保存规则
            with open('admin_standards.json', 'w', encoding='utf-8') as f:
                json.dump(rules, f, ensure_ascii=False, indent=2)
            
            self.send_json_response({"message": "Rule added successfully", "rule": new_rule})
            
        except Exception as e:
            self.send_error(500, str(e))

    def delete_admin_rule(self, rule_id):
        """删除管理员规范"""
        try:
            with open('admin_standards.json', 'r', encoding='utf-8') as f:
                rules = json.load(f)
            
            rules = [rule for rule in rules if rule['id'] != rule_id]
            
            with open('admin_standards.json', 'w', encoding='utf-8') as f:
                json.dump(rules, f, ensure_ascii=False, indent=2)
            
            self.send_json_response({"message": "Rule deleted successfully"})
            
        except Exception as e:
            self.send_error(500, str(e))

    def import_admin_rules(self):
        """导入管理员规范"""
        content_length = int(self.headers.get('Content-Length', 0))
        post_data = self.rfile.read(content_length)
        
        try:
            new_rules = json.loads(post_data.decode('utf-8'))
            
            # 加载现有规则
            try:
                with open('admin_standards.json', 'r', encoding='utf-8') as f:
                    rules = json.load(f)
            except FileNotFoundError:
                rules = []
            
            # 添加新规则
            for rule in new_rules:
                if 'id' not in rule:
                    rule['id'] = f"admin_{int(time.time())}"
                if 'created_at' not in rule:
                    rule['created_at'] = time.strftime('%Y-%m-%d')
                rules.append(rule)
            
            # 保存规则
            with open('admin_standards.json', 'w', encoding='utf-8') as f:
                json.dump(rules, f, ensure_ascii=False, indent=2)
            
            self.send_json_response({"message": "Rules imported successfully", "count": len(new_rules)})
            
        except Exception as e:
            self.send_error(500, str(e))

    def clear_admin_rules(self):
        """清空所有管理员规范"""
        try:
            with open('admin_standards.json', 'w', encoding='utf-8') as f:
                json.dump([], f, ensure_ascii=False, indent=2)
            
            self.send_json_response({"message": "All rules cleared"})
            
        except Exception as e:
            self.send_error(500, str(e))

    def send_json_response(self, data):
        """发送JSON响应"""
        response_data = json.dumps(data, ensure_ascii=False, indent=2)
        response_bytes = response_data.encode('utf-8')
        
        self.send_response(200)
        self.send_header('Content-Type', 'application/json; charset=utf-8')
        self.send_header('Content-Length', str(len(response_bytes)))
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type, X-Admin-Token')
        self.end_headers()
        self.wfile.write(response_bytes)
    
    def end_headers(self):
        """重写end_headers以添加CORS支持"""
        super().end_headers()

def start_server():
    """启动服务器"""
    PORT = 8000
    
    # 确保必要的目录存在
    os.makedirs('./data/results', exist_ok=True)
    os.makedirs('./data/uploads', exist_ok=True)
    
    with socketserver.TCPServer(("", PORT), BIMRequestHandler) as httpd:
        print(f"🚀 BIM智能安全分析平台已启动")
        print(f"📍 访问地址: http://localhost:{PORT}")
        print(f"📁 静态文件目录: {os.getcwd()}")
        print(f"🎯 主页面: http://localhost:{PORT}/static/index.html")
        print(f"🤖 AI规则库: http://localhost:{PORT}/ai-rules")
        print("\n" + "="*50)
        print("按 Ctrl+C 停止服务器")
        
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\n🛑 服务器已停止")

if __name__ == "__main__":
    start_server()